package springboot.demo.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springboot.demo.annotation.NotProfile;
import springboot.demo.bean.User;
import springboot.demo.constant.UserConstant;
import springboot.demo.converter.UserConverter;
import springboot.demo.dto.LoginRequest;
import springboot.demo.dto.ResultDTO;
import springboot.demo.dto.UserDto;
import springboot.demo.service.UserService;
import springboot.demo.util.JwtUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * 用户控制器
 * 处理用户相关的HTTP请求
 */
@Tag(name = "用户管理", description = "用户相关的接口")
@RestController
@RequestMapping("/v1/user")
@NotProfile("simple")
public class UserController {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;
    
    /**
     * 认证管理器
     * 用于处理用户认证
     */
    @Autowired
    private AuthenticationManager authenticationManager;
    
    /**
     * JWT工具类
     * 用于生成和验证JWT令牌
     */
    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 用户注册
     * @param userDto 用户信息
     * @return 注册结果
     */
    @Operation(summary = "用户注册", description = "注册新用户，密码使用BCrypt加密")
    @PostMapping("/register")
    public ResultDTO register(
            @Parameter(description = "用户注册信息", required = true)
            @Validated @RequestBody UserDto userDto) {
        LOGGER.info("用户注册请求 - userDto: {}", userDto);
        
        try {
            // 保存原始密码用于后续登录
            String rawPassword = userDto.getPassword();
            
            // 使用MapStruct转换
            User user = UserConverter.INSTANCE.toUser(userDto);
            // 使用Spring Security的PasswordEncoder加密密码
            user.setPassword(passwordEncoder.encode(rawPassword));
            
            boolean success = userService.register(user);
            if (success) {
                LOGGER.info("用户注册成功 - loginname: {}", userDto.getLoginname());
                // 注册成功后自动登录，使用原始密码
                Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(userDto.getLoginname(), rawPassword)
                );
                UserDetails userDetails = (UserDetails) authentication.getPrincipal();
                String token = jwtUtil.generateToken(userDetails);
                
                Map<String, Object> response = new HashMap<>();
                response.put("message", UserConstant.SuccessMessage.REGISTER_SUCCESS);
                response.put("token", token);
                
                return ResultDTO.success(response);
            } else {
                LOGGER.warn("用户注册失败 - loginname: {}", userDto.getLoginname());
                return ResultDTO.interError(UserConstant.ErrorMessage.USERNAME_EXISTS);
            }
        } catch (Exception e) {
            LOGGER.error("用户注册异常 - loginname: {}, error: {}", userDto.getLoginname(), e.getMessage(), e);
            return ResultDTO.interError(UserConstant.ErrorMessage.REGISTER_FAILED + e.getMessage());
        }
    }
    
    /**
     * 用户登录接口
     * 验证用户身份并返回JWT令牌
     *
     * 处理流程：
     * 1. 接收登录请求参数
     * 2. 使用Spring Security进行身份验证
     * 3. 验证成功后生成JWT令牌
     * 4. 返回令牌给客户端
     *
     * @param loginRequest 登录请求，包含用户名和密码
     * @return 登录结果，包含JWT令牌
     */
    @Operation(summary = "用户登录", description = "用户登录并获取JWT token")
    @PostMapping("/login")
    public ResultDTO login(
            @Parameter(description = "登录信息", required = true)
            @Validated @RequestBody LoginRequest loginRequest) {
        LOGGER.info("用户登录请求 - loginname: {}", loginRequest.getLoginname());
        
        try {
            // 使用Spring Security进行身份验证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginRequest.getLoginname(), loginRequest.getPassword())
            );
            
            // 获取认证成功的用户详情
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            // 生成JWT令牌
            String token = jwtUtil.generateToken(userDetails);
            
            // 构建响应数据
            Map<String, String> response = new HashMap<>();
            response.put("token", token);
            
            LOGGER.info("用户登录成功 - loginname: {}", loginRequest.getLoginname());
            return ResultDTO.success(response);
        } catch (Exception e) {
            LOGGER.error("用户登录失败 - loginname: {}, error: {}", loginRequest.getLoginname(), e.getMessage(), e);
            return ResultDTO.interError("登录失败：" + e.getMessage());
        }
    }
} 